home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 2 / ETO Development Tools 2.iso / Essentials / Developer Essentials Nov 90 / Apple II / Apple.II.partition / Utilities / rTutors / part3.2 / rTutor.cc next >
Encoding:
C/C++ Source or Header  |  1990-05-20  |  13.3 KB  |  315 lines  |  [TEXT/pdos]

  1. /* PROGRAM R.Tutor  */
  2. /* (a home-grown tutorial for writing applications using resources */
  3. /* Part 1 - starting up & shutting down the tools from a ToolStartup */
  4. /*          list kept in a resource */
  5. /* Part 2 - add a menu bar that is kept in a resource */
  6. /* Part 3 - add the event loop so that the menus "come alive" and put up a */
  7. /*          window that is defined in the resource fork */
  8. /* Part 3.2 - change "About" box from a simple beep into an Alert Window and */
  9. /*            redo the Rez and MAKE file so that we can avoid re-compiling */
  10. /*            the the parts that haven't changed and also to show off some of */
  11. /*            Rez's special abilities such as including already compiled */
  12. /*            resources from another file and appending Rez's output to an */
  13. /*            already existing resource without wiping out the existing */
  14. /*            resources... */
  15.  
  16. #include <types.h>
  17. #include <INTMATH.h>
  18. #include <MEMORY.h>
  19. #include <MISCTOOL.h>
  20. #include <LOCATOR.h>
  21. #include <DESK.H>
  22. #include <QUICKDRAW.h>
  23. #include <EVENT.h>
  24. #include <CONTROL.h>
  25. #include <WINDOW.h>    
  26. #include <MENU.h>    
  27. #include <GSOS.h>
  28. #include <Resources.h>
  29.  
  30. #define  kStartStopID    1L    /* used when starting and shutting down tools */
  31.  
  32. /*---------------------- Menus & Menu Bars ---------------------------*/
  33. #define  kMenuBarID      1L   /* resource ID of the menu bar itself */
  34.  
  35.     /* define all the menu id's */
  36. #define  kAppleMenuID   1000  /* resource ID of the Apple menu */
  37. #define  kFileMenuID    2000  /* resource ID of the File menu */
  38. #define  kEditMenuID    3000  /* resource ID of the Edit menu */
  39.  
  40.     /* now, define the menu item id's */
  41. #define   kAboutBoxID   1001  /* resource ID of the About Box menu item */ 
  42.  
  43. #define   kNewItemID    2001  /* resource ID of the New Item in File menu */
  44. #define   kOpenItemID   2002  /* resource ID of the Open item in File menu */ 
  45. #define   kCloseItemID   255  /* the "Close" item */
  46. #define   kSaveItemID   2004  /* the "Save" item */
  47. #define   kSaveAsItemID 2005  /* the "Save As..." item */
  48. #define   kRevertItemID 2006  /* the "Revert to Saved" item */
  49. #define   kPageItemID   2007  /* the "Page Setup..." item */
  50. #define   kPrintItemID  2008  /* the "Print..." item */
  51. #define   kQuitItemID   2009  /* the "Quit" item */
  52.  
  53. #define   kUndoItemID      250  /* the "Undo" item */
  54. #define   kCutItemID       251  /* the "Cut" item */
  55. #define   kCopyItemID      252  /* the "Copy" item */
  56. #define   kPasteItemID     253  /* the "Paste" item */
  57. #define   kClearItemID     254  /* the "Clear" item */
  58. #define   kSelectItemID   3001  /* the "Select All" item */
  59. #define   kShowClipItemID 3002  /* the "Show ClipBoard" item */
  60.  
  61.     /* define the resource ID's for all windows used by this app */
  62. #define myWindowID    2362L  /* window's resource ID = 2362 */
  63.  
  64. /* declare the constants for our TaskMaster event mask */
  65. #define   kMyTaskMask    0x001FFFFFL  /* this mask is for TaskMaster itself */
  66. #define   kMyEventMask    0xFFFF      /* this mask is passed to GetNextEvent */
  67.  
  68. /* declare the global variable that we'll use with TaskMaster */
  69. WmTaskRec    gMyEvent;
  70.  
  71.     
  72. /* declare all of the global variables that we'll be using */    
  73. unsigned   gMyMemID;    /* holds the ID returned by MMStartup */
  74. Ref       gToolListRef; /* the list of tools used to start and stop the tools */
  75. Boolean   gPunt;        /* TRUE if it's time to quit the app */
  76.  
  77.  
  78. /* ------------------------------------------------------------------------ */
  79. /* the following procedure is responsible for putting up the About box */
  80.  
  81. #define kAboutStr    100L /* define the constant for the About box's string */
  82.  
  83. do_show_about()
  84. {    
  85.     /* change the beep into an Alert Window - grab the Alert from a resource */
  86.     word pickedButton;
  87.     pickedButton = AlertWindow(0x0004,   /* alert string is in resource fork */
  88.                                            /* and is a "C" string */
  89.                                NULL,       /* not used right now */
  90.                                kAboutStr); /* resource ID of Alert's string */
  91. }
  92.  
  93.  
  94. /* ------------------------------------------------------------------------ */
  95. /* the following procedure is responsible for quitting the app */
  96.  
  97. do_quit_app()
  98. {
  99.   /* we actually just set the "quit" flag and let the real quitting happen */
  100.   /* in the main event loop.  Later, we would add code here to cope with */
  101.   /* closing all open windows, saving their contents, etc. */
  102.     
  103.     gPunt = TRUE;
  104. }
  105.  
  106.  
  107. /* ------------------------------------------------------------------------ */
  108. /* the following procedure is responsible for dealing with items picked */
  109. /* from the menus by the user */
  110.  
  111. do_menu_events()
  112. {
  113.  
  114.  unsigned int   pickedMenuID; /*ID of menu the user just picked an item from */
  115.  unsigned int   pickedItemID; /* ID of item the user just picked */
  116.  
  117.  /* the hi-word of wmTaskData is the menu ID */
  118.  pickedMenuID = HiWord(gMyEvent.wmTaskData);
  119.  
  120.  /* the lo-word of wmTaskData is the item ID */
  121.  pickedItemID = LoWord(gMyEvent.wmTaskData);
  122.     
  123.     switch(pickedItemID) 
  124.     {
  125.      case kAboutBoxID : do_show_about();    /* show the About box */
  126.                           break;
  127.      case kNewItemID    : break;            /* that's all for this item */
  128.      case kOpenItemID   : break;            /* that's all for this item */
  129.      case kCloseItemID  : break;            /* that's all for this item */
  130.      case kSaveItemID   : break;            /* that's all for this item */
  131.      case kSaveAsItemID : break;            /* that's all for this item */
  132.      case kRevertItemID : break;            /* that's all for this item */
  133.      case kPageItemID   : break;            /* that's all for this item */
  134.      case kPrintItemID  : break;            /* that's all for this item */
  135.      case kQuitItemID   : do_quit_app();    /* sets gPunt to TRUE  */
  136.                           break;
  137.      case kUndoItemID   : break;            /* that's all for this item */
  138.      case kCutItemID    : break;            /* that's all for this item */
  139.      case kCopyItemID   : break;            /* that's all for this item */
  140.      case kPasteItemID  : break;            /* that's all for this item */
  141.      case kClearItemID  : break;            /* that's all for this item */
  142.      case kSelectItemID : break;            /* that's all for this item */
  143.      case kShowClipItemID : break;          /* that's all for this item */
  144.         
  145.      default: ; /* always have a default action in case something goes wrong */
  146.  
  147.     } /* end of the "switch" statement */
  148.  
  149.     /* Turn off the highlighting on the menu the user picked the item from. */
  150.     /* Then return to the main event loop to see what we'll do next. */
  151.     HiliteMenu(FALSE,pickedMenuID);
  152. }
  153.  
  154.  
  155. /* ------------------------------------------------------------------------ */
  156. /* the following procedure installs the menu bar from a resource */
  157.  
  158. do_make_menus()
  159.    MenuBarRecHndl my_mbar_hndl;
  160.    word menu_bar_height; 
  161.   { 
  162.  
  163.    /* the next three calls are ALL required to bring the menu bar in from */
  164.    /* the resource fork AND make it the current system menu bar.  For */
  165.    /* details, see the IIGS Toolbox Reference, under NewMenuBar2  */
  166.   my_mbar_hndl = NewMenuBar2(refIsResource, kMenuBarID, nil); 
  167.   SetSysBar(my_mbar_hndl); 
  168.   SetMenuBar(nil);
  169.  
  170.   /* now, add NDA's, adjust the sizes of the menus, and draw the menu bar */
  171.   /* kAppleMenuID used to be defined as a long and had to be cast to a */
  172.   /* word here.  It's been redefined to be only a word in size, so the */
  173.   /* casting is no longer needed. */
  174.   FixAppleMenu(kAppleMenuID); /* adds NDA's */
  175.   menu_bar_height =  FixMenuBar(); /* adjust the sizes */
  176.   DrawMenuBar();  /* draw the new menu bar and enjoy! */ 
  177.   }
  178. }
  179.  
  180. /* ------------------------------------------------------------------------ */
  181. /* the following procedure is responsible for starting the tools (using the */
  182. /* list in a resource) if the SartupTools call fails, then gPunt will */
  183. /* contain "TRUE", so we can abort the app the global variable for this app's */
  184. /* memory id is acquired here as well. */
  185.  
  186. do_init_rom()
  187. {
  188.     gMyMemID = _ownerid; /* find out our memory id & save it for later */
  189.  
  190.     /* crank 'em up! - make sure that kStartStopID is defined as a long!!! */
  191.     gToolListRef = StartUpTools(gMyMemID,refIsResource,kStartStopID);
  192.     
  193.     if (_toolErr == noError)
  194.       {      /* there was no error, so the app can continue starting up */
  195.         gPunt = FALSE;
  196.       }
  197.     else
  198.       {     /* something went wrong, so set gPunt to indicate the failure */
  199.         gPunt = TRUE;
  200.       }
  201. }
  202.  
  203.  
  204. /* ------------------------------------------------------------------------ */
  205. /* the following procedure draws the contents of the window that we created */
  206. /* from the template in the resource fork.  Any time the window's content */
  207. /* region needs to be redrawn, this routine gets called.  Put a SysBeep() */
  208. /* call in here if you want to investigate when this routine gets called. */
  209. /* That will cause a beep every time this routine gets called... */
  210.  
  211. drawMyContents()
  212. {
  213.     /* since all of the contents of our window are actually controls right */
  214.     /* now, we can redraw the contents just by calling DrawControls. Later, */
  215.     /* we could add code to draw other, non-control stuff. */
  216.     
  217.     GrafPortPtr   currentGrafPortPtr; /* pointer to current Graf Port */
  218.  
  219.     currentGrafPortPtr = GetPort();  /* grab the pointer to current port */
  220.     DrawControls(currentGrafPortPtr); /* draw the controls in that port */
  221. }
  222.  
  223.  
  224. /* ------------------------------------------------------------------------ */
  225. /* the following procedure creates a window using a template that is kept */
  226. /* in the application's resource fork */
  227.  
  228. do_make_window()
  229. {
  230.     /* since we only have one window and it can't be closed, we won't */
  231.     /* bother to keep the grafPortPtr in a global.  We can always get it */
  232.     /* back by calling FrontWindow().  Later, when we add multiple windows, */
  233.     /* we'll want a better way to keep track of the grafPortPtr to each */
  234.     /* window, but for now I'd like to keep it simple. */
  235.     
  236.  GrafPortPtr    myWndwPtr;
  237.  CtlRecHndl     myCtlRecHndl;
  238.     
  239.  myWndwPtr = NewWindow2(NIL, /* use "default" title string from param block */
  240.                         NIL, /* use "default" refCon from param block */
  241.                         drawMyContents, /* procedure that draws contents */
  242.                         NIL, /* use std def proc for this window */
  243.                         refIsResource,   /* template is in a resource */
  244.                         myWindowID,       /* resource ID of our window */
  245.                         rWindParam1);    /* template is of param type 1 */
  246.  
  247.     /* According to Apple IIGS Tech Note #82 (Controlling the Control Mgr) */
  248.     /* NewWindow2 does NOT set the grafPort to the newly created grafPort */
  249.     /* so it's possible for our controls to NOT be installed correctly */
  250.     /* and for the call to trash memory. So, we avoid the problem by doing */
  251.     /* exactly waht Tech Note #82 tells us to do -> don't let NewWindow2 */
  252.     /* install our controls for us.  We do this by putting NIL in the */
  253.     /* "p1ControlList" field of the rWindParam1 record (in our Rez source) */
  254.     /* and calling NewControl2 to put the controls in the window - AFTER */
  255.     /* setting the grafPort ourselves! */
  256.  
  257.     SetPort(myWndwPtr); /* set the Graf Port to the newly created window's */
  258.     myCtlRecHndl = NewControl2(myWndwPtr,    /* window to put controls in */
  259.                                resourceToResource, /* list is in resource */
  260.                                myWindowID);  /* resource ID of control list */
  261. }
  262.  
  263. /* ------------------------------------------------------------------------ */
  264. /* the following procedure is the main event loop. It runs until gPunt is */
  265. /* set to TRUE by the user picking "Quit" from the File menu. */
  266.  
  267. do_main_event()
  268. {
  269.   word  myTaskCode;  /* used to hold the task codes returned by Task Master */
  270.  
  271.   /* tell Task Master which events it can do */
  272.   /* we're lazy, so let it handle everything possible! */
  273.   gMyEvent.wmTaskMask = kMyTaskMask;
  274.  
  275.   while(!gPunt)  /* keep calling Task Master until "Quit" has been selected */
  276.   {
  277.     myTaskCode = TaskMaster(kMyEventMask, &gMyEvent);
  278.     switch(myTaskCode) 
  279.       {
  280.         case wInGoAway:
  281.            break;
  282.         case wInSpecial:
  283.         case wInMenuBar:
  284.            do_menu_events();
  285.             break;
  286.         default:  break; /* always have a default */
  287.       }    /* end of the switch statement */        
  288.     } /* end of the "while" */
  289. } /* end of do_main_event */
  290.  
  291.  
  292. /* ------------------------------------------------------------------------ */
  293. /* the following procedure is the main application itself. */
  294. /* don't forget to add the code that will check the message center to see if */
  295. /* this app was launched by clicking on its icon or by clicking on a data */
  296. /* file created by this app.  If the data file was clicked on, then grab its */
  297. /* name out of the message center and open it instead of opening the */
  298. /* untitled window. */
  299.  
  300. main()
  301. {    
  302.     do_init_rom();    /* get my memory id, start the tools, & set gPunt */
  303.     if (gPunt == FALSE)
  304.       {
  305.         do_make_menus();  /* insert the menu bar */
  306.         do_make_window(); /* create a new window from the resource fork */
  307.         InitCursor();     /* this changes the cursor to the "normal" one. */
  308.                           /* It was left as a watch cursor when the tools */
  309.                           /* were started up. */
  310.         do_main_event();
  311.       }
  312.     ShutDownTools(refIsHandle,gToolListRef); /* shut down the tools and quit */
  313. } /* end of main program */
  314.